package com.googlecode.monitoria.server.persistence.dao;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;

import com.googlecode.monitoria.client.beans.Persistable;
import com.googlecode.monitoria.client.beans.User;
import com.googlecode.monitoria.server.persistence.util.HibernateUtil;

/**
 * @author Ricardo Araujo Santos - ricardo@lsd.ufcg.edu.br
 *
 * @param <T> Any class implementing {@link Persistable} interface.
 */
public class AbstractDAO<T extends Persistable> implements DAO<T>{
	
	protected Class<T> persistentClass;
	
	/**
	 * Default constructor.
	 */
	@SuppressWarnings("unchecked")
	private AbstractDAO() {
		this.persistentClass = (Class<T>) ((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }
	
	/**
	 * {@inheritDoc}
	 */
	public void save(T object){
		
		assert object != null: "This database cannot save null objects";
		
		HibernateUtil.beginTransaction();
		HibernateUtil.getSession().save( object );
		HibernateUtil.commitTransaction();
	}
	
	/**
	 * {@inheritDoc}
	 */
	public void update(T object){
		
		assert object != null: "This database cannot update null objects";

		HibernateUtil.beginTransaction();
		HibernateUtil.getSession().update( object );
		HibernateUtil.commitTransaction();
	}
	
	/**
	 * {@inheritDoc}
	 */
	public void delete(T object){
		
		assert object != null: "This database cannot delete null objects";

		HibernateUtil.beginTransaction();
		HibernateUtil.getSession().delete( object );
		HibernateUtil.commitTransaction();
	}
	
	/**
	 * {@inheritDoc}
	 */
	@SuppressWarnings("unchecked")
	public T findByID( Serializable id ){
		
		assert id != null: "Null primary keys are not allowed in this database.";
		
		HibernateUtil.beginTransaction();
		T object = (T) HibernateUtil.getSession().get( persistentClass, id);
		HibernateUtil.commitTransaction();
		return object;
	}
	
	/**
	 * @author Ricardo Araujo Santos - ricardo@lsd.ufcg.edu.br
	 *
	 */
	public static class UserDAO extends AbstractDAO<User>{}
	
	/**
	 * 
	 * @author Ricardo Araujo Santos - ricardo@lsd.ufcg.edu.br
	 */
	public static class DAOFactory{
		
		/**
		 * @return
		 */
		public static UserDAO getUserDAO() {
			return new UserDAO();
		}
	}
}
